{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "f1f3dbff-8995-4f83-b510-03faba6f3c33",
   "metadata": {},
   "outputs": [],
   "source": [
    "import math\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1242f2a7-a34c-4da6-b021-725a53fb3475",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义函数\n",
    "def f(x):\n",
    "    return 3*x**2 - 4*x + 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "98529717-4fe5-428f-a8f5-8162c826cedc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20.0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f(3.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "fd049d2a-3426-4719-a35a-6c8dc16f1cf0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-5.   -4.75 -4.5  -4.25 -4.   -3.75 -3.5  -3.25 -3.   -2.75 -2.5  -2.25\n",
      " -2.   -1.75 -1.5  -1.25 -1.   -0.75 -0.5  -0.25  0.    0.25  0.5   0.75\n",
      "  1.    1.25  1.5   1.75  2.    2.25  2.5   2.75  3.    3.25  3.5   3.75\n",
      "  4.    4.25  4.5   4.75]\n",
      "[100.      91.6875  83.75    76.1875  69.      62.1875  55.75    49.6875\n",
      "  44.      38.6875  33.75    29.1875  25.      21.1875  17.75    14.6875\n",
      "  12.       9.6875   7.75     6.1875   5.       4.1875   3.75     3.6875\n",
      "   4.       4.6875   5.75     7.1875   9.      11.1875  13.75    16.6875\n",
      "  20.      23.6875  27.75    32.1875  37.      42.1875  47.75    53.6875]\n"
     ]
    }
   ],
   "source": [
    "xs = np.arange(-5.0, 5.0, 0.25) # 范围 -5 到 5，但不包含 5，步长为 0.25\n",
    "print(xs)\n",
    "ys = f(xs)\n",
    "print(ys)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "44d6f426-1075-4e87-8555-d4e13f21e4c6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x243f794a380>]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(xs, ys)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "546c0b64-2ec5-4d99-8aae-7e87f927caeb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20.014003000000002"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h = 0.001\n",
    "x = 3.0\n",
    "f(x + h)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "ae208b4f-f667-47de-add6-e3679d6d491e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.01400300000000243"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h = 0.001\n",
    "x = 3.0\n",
    "f(x + h) - f(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "46950436-1a15-4f2a-b037-eec46d8d8fbb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "14.210854715202004"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h = 0.00000000000001\n",
    "x = 3.0\n",
    "(f(x + h) - f(x)) / h # 表示 x = 3 时的导数（ h 趋向于 0 时的比值）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "89c8309d-e1de-478b-b5e1-823cdcdbc6d8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h = 0.00000000000001\n",
    "x = 2/3\n",
    "(f(x + h) - f(x)) / h # 表示 x = 2/3 时的导数（ h 趋向于 0 时的比值）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cad8eb3-f39a-455d-bbee-57df966a9c5c",
   "metadata": {},
   "source": [
    "解了导数的概念，现在开始神经网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "aa1a5893-93fb-41c5-a287-77d6c168c285",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Value:\n",
    "    def __init__(self, data):\n",
    "        self.data = data\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"Value(data={self.data})\"\n",
    "\n",
    "    def __add__(self, other):\n",
    "        out = Value(self.data + other.data)\n",
    "        return out\n",
    "\n",
    "    def __mul__(self, other):\n",
    "        out = Value(self.data * other.data)\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "148790b4-253c-4437-a9d9-628bc5dea1bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value(data=-1.0)\n",
      "Value(data=-6.0)\n"
     ]
    }
   ],
   "source": [
    "a = Value(2.0)\n",
    "b = Value(-3.0)\n",
    "print(a + b)\n",
    "print(a * b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "29a16140-f8f7-49f0-b7b1-7ffb30a37489",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Value:\n",
    "    def __init__(self, data, _children=()):\n",
    "        self.data = data\n",
    "        self._prev = set(_children) # 前驱计算节点\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"Value(data={self.data})\"\n",
    "\n",
    "    def __add__(self, other):\n",
    "        out = Value(self.data + other.data, (self, other))\n",
    "        return out\n",
    "\n",
    "    def __mul__(self, other):\n",
    "        out = Value(self.data * other.data, (self, other))\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "921965b5-d423-4b3a-bd92-a7cc6095db29",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value(data=-6.0)\n",
      "Value(data=4.0)\n"
     ]
    }
   ],
   "source": [
    "a = Value(2.0)\n",
    "b = Value(-3.0)\n",
    "c = Value(10.0)\n",
    "d = Value(20.0)\n",
    "e = a*b\n",
    "f = e + c\n",
    "print(e)\n",
    "print(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "927dc680-493c-4960-985b-1a39d2ce4f6d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{Value(data=-3.0), Value(data=2.0)}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e._prev # 获取前驱计算节点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "ca9caa8b-3332-4a86-aa21-1424744105a2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{Value(data=-6.0), Value(data=10.0)}"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f._prev # 获取前驱计算节点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "e88eecdf-1aff-42dc-8f53-846127d33c69",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Value:\n",
    "    def __init__(self, data, _children=(), _op=''):\n",
    "        self.data = data\n",
    "        self._prev = set(_children) # 前驱计算节点\n",
    "        self._op = _op # 计算符号\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"Value(data={self.data})\"\n",
    "\n",
    "    def __add__(self, other):\n",
    "        out = Value(self.data + other.data, (self, other), '+')\n",
    "        return out\n",
    "\n",
    "    def __mul__(self, other):\n",
    "        out = Value(self.data * other.data, (self, other), '*')\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "f24072d8-76d0-4528-bfb6-5469bd97b97d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value(data=-3.0)\n",
      "Value(data=-21.0)\n"
     ]
    }
   ],
   "source": [
    "a = Value(2.0)\n",
    "b = Value(-5.0)\n",
    "c = Value(7.0)\n",
    "e = a + b\n",
    "L = e * c\n",
    "print(e)\n",
    "print(L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "e82a4c24-7ad9-481a-8ae2-8a1edd08a2ac",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'+'"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "e._op # 获取计算符号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "07225428-e7ef-42fa-a070-15fe8247c17c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'*'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L._op # 获取计算符号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "1c895b7a-9569-4273-895a-7a0fbb73f8d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "from graphviz import Digraph\n",
    "\n",
    "def trace(root):\n",
    "    nodes, edges = set(), set()\n",
    "    def build(v):\n",
    "        if v not in nodes:\n",
    "            nodes.add(v)\n",
    "            for child in v._prev:\n",
    "                edges.add((child, v))\n",
    "                build(child)\n",
    "    build(root)\n",
    "    return nodes, edges\n",
    "\n",
    "def draw_dot(root):\n",
    "    nodes, edges = trace(root)\n",
    "    dot = Digraph(format='svg', graph_attr={'rankdir': 'LR'})\n",
    "\n",
    "    for n in nodes:\n",
    "        dot.node(name=str(id(n)), label = \"{ data %.4f }\" % (n.data), shape='record')\n",
    "        if n._op:\n",
    "            dot.node(name=str(id(n)) + n._op, label=n._op)\n",
    "            dot.edge(str(id(n)) + n._op, str(id(n)))\n",
    "\n",
    "    for n1, n2 in edges:\n",
    "        dot.edge(str(id(n1)), str(id(n2)) + n2._op)\n",
    "\n",
    "    return dot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "9f0f7ca6-51bc-4bad-a0d0-b84d13bcf128",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 14.0.2 (20251019.1705)\n",
       " -->\n",
       "<!-- Pages: 1 -->\n",
       "<svg width=\"520pt\" height=\"127pt\"\n",
       " viewBox=\"0.00 0.00 520.00 127.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 123)\">\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-123 515.5,-123 515.5,4 -4,4\"/>\n",
       "<!-- 2347606849040 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>2347606849040</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"210.25,-27.5 210.25,-63.5 294.5,-63.5 294.5,-27.5 210.25,-27.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"252.38\" y=\"-40.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;3.0000</text>\n",
       "</g>\n",
       "<!-- 2347606842992* -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>2347606842992*</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"357.5\" cy=\"-72.5\" rx=\"27\" ry=\"18\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"357.5\" y=\"-67.45\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">*</text>\n",
       "</g>\n",
       "<!-- 2347606849040&#45;&gt;2347606842992* -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>2347606849040&#45;&gt;2347606842992*</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M294.73,-56.33C303.36,-58.59 312.38,-60.95 320.79,-63.15\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"319.74,-66.49 330.3,-65.64 321.51,-59.72 319.74,-66.49\"/>\n",
       "</g>\n",
       "<!-- 2347606849040+ -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>2347606849040+</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"147.25\" cy=\"-45.5\" rx=\"27\" ry=\"18\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"147.25\" y=\"-40.45\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">+</text>\n",
       "</g>\n",
       "<!-- 2347606849040+&#45;&gt;2347606849040 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>2347606849040+&#45;&gt;2347606849040</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M174.54,-45.5C181.92,-45.5 190.23,-45.5 198.57,-45.5\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"198.39,-49 208.39,-45.5 198.39,-42 198.39,-49\"/>\n",
       "</g>\n",
       "<!-- 2347606842992 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2347606842992</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"420.5,-54.5 420.5,-90.5 511.5,-90.5 511.5,-54.5 420.5,-54.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"466\" y=\"-67.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;21.0000</text>\n",
       "</g>\n",
       "<!-- 2347606842992*&#45;&gt;2347606842992 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>2347606842992*&#45;&gt;2347606842992</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M384.83,-72.5C392.19,-72.5 400.5,-72.5 408.89,-72.5\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"408.81,-76 418.81,-72.5 408.81,-69 408.81,-76\"/>\n",
       "</g>\n",
       "<!-- 2347606270752 -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>2347606270752</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"2.25,-55.5 2.25,-91.5 82,-91.5 82,-55.5 2.25,-55.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"42.12\" y=\"-68.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data 2.0000</text>\n",
       "</g>\n",
       "<!-- 2347606270752&#45;&gt;2347606849040+ -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>2347606270752&#45;&gt;2347606849040+</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M82.41,-62.83C91.69,-60.31 101.54,-57.64 110.65,-55.17\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"111.51,-58.56 120.24,-52.56 109.67,-51.8 111.51,-58.56\"/>\n",
       "</g>\n",
       "<!-- 2347606263696 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>2347606263696</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"0,-0.5 0,-36.5 84.25,-36.5 84.25,-0.5 0,-0.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"42.12\" y=\"-13.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;5.0000</text>\n",
       "</g>\n",
       "<!-- 2347606263696&#45;&gt;2347606849040+ -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>2347606263696&#45;&gt;2347606849040+</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M84.48,-29.33C93.11,-31.59 102.13,-33.95 110.54,-36.15\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"109.49,-39.49 120.05,-38.64 111.26,-32.72 109.49,-39.49\"/>\n",
       "</g>\n",
       "<!-- 2347606270368 -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>2347606270368</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"212.5,-82.5 212.5,-118.5 292.25,-118.5 292.25,-82.5 212.5,-82.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"252.38\" y=\"-95.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data 7.0000</text>\n",
       "</g>\n",
       "<!-- 2347606270368&#45;&gt;2347606842992* -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>2347606270368&#45;&gt;2347606842992*</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M292.66,-89.83C301.94,-87.31 311.79,-84.64 320.9,-82.17\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"321.76,-85.56 330.49,-79.56 319.92,-78.8 321.76,-85.56\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x222984b7250>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "draw_dot(L)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8a85102-1483-4996-a1ea-ddc9f8ca41c6",
   "metadata": {},
   "source": [
    "上面的这个视图展示的就是一个前向传播的可视化。接下来是 L 对 a，f 对 b，f 对 e，f 对 c 的导数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "5b565d35-4962-4914-9290-31cfe08ed594",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Value:\n",
    "    def __init__(self, data, _children=(), _op=''):\n",
    "        self.data = data\n",
    "        self.grad = 0.0 # 梯度（向量）\n",
    "        self._prev = set(_children) # 计算节点\n",
    "        self._op = _op # 计算符号\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f\"Value(data={self.data})\"\n",
    "\n",
    "    def __add__(self, other):\n",
    "        out = Value(self.data + other.data, (self, other), '+')\n",
    "        return out\n",
    "\n",
    "    def __mul__(self, other):\n",
    "        out = Value(self.data * other.data, (self, other), '*')\n",
    "        return out"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "115f092d-7546-4908-a05c-f94ffe201d11",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Value(data=-3.0)\n",
      "Value(data=-21.0)\n"
     ]
    }
   ],
   "source": [
    "a = Value(2.0)\n",
    "b = Value(-5.0)\n",
    "c = Value(7.0)\n",
    "e = a + b\n",
    "L = e * c\n",
    "print(e)\n",
    "print(L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "e5033cb5-67a6-419b-9a6b-c62a1da19e19",
   "metadata": {},
   "outputs": [],
   "source": [
    "from graphviz import Digraph\n",
    "\n",
    "def trace(root):\n",
    "    nodes, edges = set(), set()\n",
    "    def build(v):\n",
    "        if v not in nodes:\n",
    "            nodes.add(v)\n",
    "            for child in v._prev:\n",
    "                edges.add((child, v))\n",
    "                build(child)\n",
    "    build(root)\n",
    "    return nodes, edges\n",
    "\n",
    "def draw_dot(root):\n",
    "    nodes, edges = trace(root)\n",
    "    dot = Digraph(format='svg', graph_attr={'rankdir': 'LR'})\n",
    "\n",
    "    for n in nodes:\n",
    "        dot.node(name=str(id(n)), label = \"{ data %.4f | grad %.4f }\" % (n.data, n.grad), shape='record')\n",
    "        if n._op:\n",
    "            dot.node(name=str(id(n)) + n._op, label=n._op)\n",
    "            dot.edge(str(id(n)) + n._op, str(id(n)))\n",
    "\n",
    "    for n1, n2 in edges:\n",
    "        dot.edge(str(id(n1)), str(id(n2)) + n2._op)\n",
    "\n",
    "    return dot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "866be8b5-1a94-4c8b-ad73-81505b1199d3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 14.0.2 (20251019.1705)\n",
       " -->\n",
       "<!-- Pages: 1 -->\n",
       "<svg width=\"763pt\" height=\"127pt\"\n",
       " viewBox=\"0.00 0.00 763.00 127.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 123)\">\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-123 759.25,-123 759.25,4 -4,4\"/>\n",
       "<!-- 2490940373552 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>2490940373552</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"293.75,-82.5 293.75,-118.5 454.75,-118.5 454.75,-82.5 293.75,-82.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"333.62\" y=\"-95.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data 7.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"373.5,-83 373.5,-118.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"414.12\" y=\"-95.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 0.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373648* -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2490940373648*</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"520\" cy=\"-72.5\" rx=\"27\" ry=\"18\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"520\" y=\"-67.45\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">*</text>\n",
       "</g>\n",
       "<!-- 2490940373552&#45;&gt;2490940373648* -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>2490940373552&#45;&gt;2490940373648*</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M455.11,-84.94C464.6,-83.1 473.9,-81.28 482.34,-79.64\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"482.99,-83.08 492.14,-77.73 481.66,-76.21 482.99,-83.08\"/>\n",
       "</g>\n",
       "<!-- 2490940373648 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>2490940373648</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"583,-54.5 583,-90.5 755.25,-90.5 755.25,-54.5 583,-54.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"628.5\" y=\"-67.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;21.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"674,-55 674,-90.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"714.62\" y=\"-67.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 0.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373648*&#45;&gt;2490940373648 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>2490940373648*&#45;&gt;2490940373648</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M547.3,-72.5C554.51,-72.5 562.76,-72.5 571.5,-72.5\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"571.27,-76 581.27,-72.5 571.27,-69 571.27,-76\"/>\n",
       "</g>\n",
       "<!-- 2490940374224 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>2490940374224</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"291.5,-27.5 291.5,-63.5 457,-63.5 457,-27.5 291.5,-27.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"333.62\" y=\"-40.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;3.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"375.75,-28 375.75,-63.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"416.38\" y=\"-40.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 0.0000</text>\n",
       "</g>\n",
       "<!-- 2490940374224&#45;&gt;2490940373648* -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>2490940374224&#45;&gt;2490940373648*</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M457.2,-60.89C466,-62.54 474.58,-64.16 482.42,-65.63\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"481.72,-69.06 492.2,-67.47 483.01,-62.18 481.72,-69.06\"/>\n",
       "</g>\n",
       "<!-- 2490940374224+ -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>2490940374224+</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"228.5\" cy=\"-45.5\" rx=\"27\" ry=\"18\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"228.5\" y=\"-40.45\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">+</text>\n",
       "</g>\n",
       "<!-- 2490940374224+&#45;&gt;2490940374224 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>2490940374224+&#45;&gt;2490940374224</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M255.87,-45.5C262.97,-45.5 271.07,-45.5 279.64,-45.5\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"279.59,-49 289.59,-45.5 279.59,-42 279.59,-49\"/>\n",
       "</g>\n",
       "<!-- 2490940373216 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>2490940373216</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"2.25,-55.5 2.25,-91.5 163.25,-91.5 163.25,-55.5 2.25,-55.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"42.12\" y=\"-68.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data 2.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"82,-56 82,-91.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"122.62\" y=\"-68.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 0.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373216&#45;&gt;2490940374224+ -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>2490940373216&#45;&gt;2490940374224+</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M163.61,-57.94C173.1,-56.1 182.4,-54.28 190.84,-52.64\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"191.49,-56.08 200.64,-50.73 190.16,-49.21 191.49,-56.08\"/>\n",
       "</g>\n",
       "<!-- 2490940373792 -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>2490940373792</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"0,-0.5 0,-36.5 165.5,-36.5 165.5,-0.5 0,-0.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"42.12\" y=\"-13.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;5.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"84.25,-1 84.25,-36.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"124.88\" y=\"-13.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 0.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373792&#45;&gt;2490940374224+ -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>2490940373792&#45;&gt;2490940374224+</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M165.7,-33.89C174.5,-35.54 183.08,-37.16 190.92,-38.63\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"190.22,-42.06 200.7,-40.47 191.51,-35.18 190.22,-42.06\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x243f7a84700>"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "draw_dot(L) # 画计算图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "f1b879b4-d92e-4b1c-b7cd-e7e88e1c0115",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dL/dL: 1.0000000000012221\n",
      "dL/de: 6.999999999997897\n",
      "dL/dc: -3.0000000000001137\n",
      "dL/da: 6.999999999997897\n",
      "dL/db: 7.0000000000014495\n"
     ]
    }
   ],
   "source": [
    "def lol():\n",
    "    \n",
    "    h = 0.001\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L1 = L.data\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L2 = L.data + h # 求 L 对 L 的导数\n",
    "\n",
    "    print(\"dL/dL:\", (L2 - L1)/h);\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L1 = L.data\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    e = Value(-3.0 + h) # 求 L 对 e 的导数\n",
    "    L = e * c\n",
    "    L2 = L.data\n",
    "\n",
    "    print(\"dL/de:\", (L2 - L1)/h)\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L1 = L.data\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0 + h) # 求 L 对 c 的导数\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L2 = L.data\n",
    "\n",
    "    print(\"dL/dc:\", (L2 - L1)/h)\n",
    "\n",
    "    # dL/da = (dL / de) * (de / da) 通过链式法则\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L1 = L.data\n",
    "\n",
    "    a = Value(2.0 + h) # 求 L 对 a 的导数\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L2 = L.data\n",
    "\n",
    "    print(\"dL/da:\", (L2 - L1)/h)\n",
    "\n",
    "    # dL/db = (dL / de) * (de / db) 通过链式法则\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0)\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L1 = L.data\n",
    "\n",
    "    a = Value(2.0)\n",
    "    b = Value(-5.0 + h) # 求 L 对 b 的导数\n",
    "    c = Value(7.0)\n",
    "    e = a + b\n",
    "    L = e * c\n",
    "    L2 = L.data\n",
    "\n",
    "    print(\"dL/db:\", (L2 - L1)/h)\n",
    "\n",
    "lol()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "8a593343-085d-4228-b9c4-ad3f741089d8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/svg+xml": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 14.0.2 (20251019.1705)\n",
       " -->\n",
       "<!-- Pages: 1 -->\n",
       "<svg width=\"763pt\" height=\"127pt\"\n",
       " viewBox=\"0.00 0.00 763.00 127.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 123)\">\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-123 759.25,-123 759.25,4 -4,4\"/>\n",
       "<!-- 2490940373552 -->\n",
       "<g id=\"node1\" class=\"node\">\n",
       "<title>2490940373552</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"291.5,-82.5 291.5,-118.5 457,-118.5 457,-82.5 291.5,-82.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"331.38\" y=\"-95.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data 7.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"371.25,-83 371.25,-118.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"414.12\" y=\"-95.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad &#45;3.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373648* -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>2490940373648*</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"520\" cy=\"-72.5\" rx=\"27\" ry=\"18\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"520\" y=\"-67.45\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">*</text>\n",
       "</g>\n",
       "<!-- 2490940373552&#45;&gt;2490940373648* -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>2490940373552&#45;&gt;2490940373648*</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M457.2,-84.54C466,-82.82 474.58,-81.15 482.42,-79.62\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"483.05,-83.07 492.2,-77.72 481.71,-76.2 483.05,-83.07\"/>\n",
       "</g>\n",
       "<!-- 2490940373648 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>2490940373648</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"583,-54.5 583,-90.5 755.25,-90.5 755.25,-54.5 583,-54.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"628.5\" y=\"-67.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;21.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"674,-55 674,-90.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"714.62\" y=\"-67.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 1.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373648*&#45;&gt;2490940373648 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>2490940373648*&#45;&gt;2490940373648</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M547.3,-72.5C554.51,-72.5 562.76,-72.5 571.5,-72.5\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"571.27,-76 581.27,-72.5 571.27,-69 571.27,-76\"/>\n",
       "</g>\n",
       "<!-- 2490940374224 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>2490940374224</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"291.5,-27.5 291.5,-63.5 457,-63.5 457,-27.5 291.5,-27.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"333.62\" y=\"-40.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;3.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"375.75,-28 375.75,-63.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"416.38\" y=\"-40.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 7.0000</text>\n",
       "</g>\n",
       "<!-- 2490940374224&#45;&gt;2490940373648* -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>2490940374224&#45;&gt;2490940373648*</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M457.2,-60.89C466,-62.54 474.58,-64.16 482.42,-65.63\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"481.72,-69.06 492.2,-67.47 483.01,-62.18 481.72,-69.06\"/>\n",
       "</g>\n",
       "<!-- 2490940374224+ -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>2490940374224+</title>\n",
       "<ellipse fill=\"none\" stroke=\"black\" cx=\"228.5\" cy=\"-45.5\" rx=\"27\" ry=\"18\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"228.5\" y=\"-40.45\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">+</text>\n",
       "</g>\n",
       "<!-- 2490940374224+&#45;&gt;2490940374224 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>2490940374224+&#45;&gt;2490940374224</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M255.87,-45.5C262.97,-45.5 271.07,-45.5 279.64,-45.5\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"279.59,-49 289.59,-45.5 279.59,-42 279.59,-49\"/>\n",
       "</g>\n",
       "<!-- 2490940373216 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>2490940373216</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"2.25,-55.5 2.25,-91.5 163.25,-91.5 163.25,-55.5 2.25,-55.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"42.12\" y=\"-68.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data 2.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"82,-56 82,-91.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"122.62\" y=\"-68.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 7.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373216&#45;&gt;2490940374224+ -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>2490940373216&#45;&gt;2490940374224+</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M163.61,-57.94C173.1,-56.1 182.4,-54.28 190.84,-52.64\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"191.49,-56.08 200.64,-50.73 190.16,-49.21 191.49,-56.08\"/>\n",
       "</g>\n",
       "<!-- 2490940373792 -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>2490940373792</title>\n",
       "<polygon fill=\"none\" stroke=\"black\" points=\"0,-0.5 0,-36.5 165.5,-36.5 165.5,-0.5 0,-0.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"42.12\" y=\"-13.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">data &#45;5.0000</text>\n",
       "<polyline fill=\"none\" stroke=\"black\" points=\"84.25,-1 84.25,-36.5\"/>\n",
       "<text xml:space=\"preserve\" text-anchor=\"middle\" x=\"124.88\" y=\"-13.7\" font-family=\"Times New Roman,serif\" font-size=\"14.00\">grad 7.0000</text>\n",
       "</g>\n",
       "<!-- 2490940373792&#45;&gt;2490940374224+ -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>2490940373792&#45;&gt;2490940374224+</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M165.7,-33.89C174.5,-35.54 183.08,-37.16 190.92,-38.63\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"190.22,-42.06 200.7,-40.47 191.51,-35.18 190.22,-42.06\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.graphs.Digraph at 0x243f7a84a30>"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L.grad = 1.0\n",
    "e.grad = 7.0\n",
    "c.grad = -3.0\n",
    "a.grad = 7.0\n",
    "b.grad = 7.0\n",
    "\n",
    "draw_dot(L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c3db93a-b5f5-45dd-bde2-fa27c8649d38",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
